﻿namespace TheoryProject
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    /// <summary>
    /// Simulation Form 
    /// </summary>
    public partial class SimulationForm : Form
    {
        /// <summary>
        /// turing machine
        /// </summary>
        private Task1.TuringMachine turingMachine;

        /// <summary>
        /// simulation head
        /// </summary>
        private int simHead = 50;

        /// <summary>
        /// turing machine head
        /// </summary>
        private int tapeHead = 0;

        /// <summary>
        /// current state
        /// </summary>
        private int state = 0;

        /// <summary>
        /// Initializes a new instance of the <see cref="SimulationForm"/> class.
        /// </summary>
        /// <param name="tr">The tr.</param>
        public SimulationForm(Task1.TuringMachine tr)
        {
            try
            {
                this.InitializeComponent();
                int simHead = 50;
                this.turingMachine = tr;

                for (int i = 0; i < 100; i++)
                {
                    this.dgvSimulation.Columns.Add(string.Format("c{0}", i), string.Empty);
                    this.dgvSimulation.Columns[i].Width = 15;
                    this.dgvSimulation[i, 0].Value = "^";
                }

                int tapeLength = tr.Tape.Count;

                for (int i = 50; i < 50 + tapeLength; i++)
                {
                    if (i < 100)
                    {
                        this.dgvSimulation[i, 0].Value = tr.Tape[i - 50];
                    }
                    else
                    {
                        this.dgvSimulation.Columns.Add(string.Format("c{0}", i), string.Empty);
                        this.dgvSimulation.Columns[i].Width = 15;
                        this.dgvSimulation[i, 0].Value = tr.Tape[i - 50];
                    }
                }

                this.dgvSimulation.Rows[0].Cells[simHead].Style.BackColor = Color.Blue;
            }
            catch 
            {
                MessageBox.Show("Error Initializing the simulation ");
            }
        }

        /// <summary>
        /// Starts the sim.
        /// </summary>
        private void StartSim()
        {
            try
            {
                Task1.Transition? nextTransition;
                nextTransition = this.turingMachine.GetTransition(this.turingMachine.Tape[this.tapeHead], this.state);

                if (nextTransition != null)
                {
                    Task1.Transition temp = (Task1.Transition)nextTransition;
                    char c;
                    if (temp.Direction == Task1.Direction.LEFT)
                    {
                        c = 'L';
                    }
                    else if (temp.Direction == Task1.Direction.RIGHT)
                    {
                        c = 'R';
                    }
                    else
                    {
                        c = 'S';
                    }

                    this.lblTransitionUsed.Text = string.Format("( q{0}, {1} ) = ( q{2} , {3} , {4} )", temp.State, temp.InputChar == '\0' ? '^' : temp.InputChar, temp.NextState, temp.OutputChar == '\0' ? '^' : temp.OutputChar, c);

                    this.state = temp.NextState;
                    this.turingMachine.Tape[this.tapeHead] = temp.OutputChar;
                    this.dgvSimulation[this.simHead, 0].Value = (temp.OutputChar == '\0') ? '^' : temp.OutputChar;

                    if (temp.Direction == Task1.Direction.LEFT)
                    {
                        this.tapeHead--;
                        this.dgvSimulation.Rows[0].Cells[this.simHead].Style.BackColor = Color.White;
                        this.simHead--;
                        this.dgvSimulation.Rows[0].Cells[this.simHead].Style.BackColor = Color.Blue;
                        if (this.tapeHead < 0)
                        {
                            this.turingMachine.Tape.Insert(0, '\0');
                            this.tapeHead = 0;
                        }
                    }
                    else if (temp.Direction == Task1.Direction.RIGHT)
                    {
                        this.tapeHead++;
                        this.dgvSimulation.Rows[0].Cells[this.simHead].Style.BackColor = Color.White;
                        this.simHead++;
                        this.dgvSimulation.Rows[0].Cells[this.simHead].Style.BackColor = Color.Blue;
                        if (this.tapeHead == this.turingMachine.Tape.Count)
                        {
                            this.turingMachine.Tape.Insert(this.turingMachine.Tape.Count, '\0');
                            this.tapeHead = this.turingMachine.Tape.Count - 1;
                        }
                    }

                    if (this.turingMachine.IsFinalState(temp.NextState))
                    {
                        MessageBox.Show("Simulation Finished with state Accept");
                    }
                }
                else
                {
                    MessageBox.Show("Simulation Finished with state reject");
                }
            }
            catch 
            {
                MessageBox.Show("Error in this simulation step");
            }
        }

        /// <summary>
        /// Handles the Click event of the button1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                this.StartSim();
            }
            catch
            {
                MessageBox.Show("Error ");
            }
        }
    }
}
